package com.linser.gistools.common.datastore.model;

import com.linser.gistools.utils.TransformUtil;
import com.linser.gistools.utils.enums.CoordinateType;
import org.geotools.data.*;
import org.geotools.data.collection.ListFeatureCollection;
import org.geotools.data.simple.SimpleFeatureCollection;
import org.geotools.data.simple.SimpleFeatureIterator;
import org.geotools.feature.NameImpl;
import org.geotools.feature.simple.SimpleFeatureBuilder;
import org.geotools.feature.simple.SimpleFeatureTypeBuilder;
import org.geotools.feature.type.GeometryDescriptorImpl;
import org.geotools.feature.type.GeometryTypeImpl;
import org.geotools.jdbc.JDBCDataStore;
import org.locationtech.jts.geom.Geometry;
import org.locationtech.jts.geom.LineString;
import org.locationtech.jts.geom.Point;
import org.locationtech.jts.geom.Polygon;
import org.opengis.feature.Property;
import org.opengis.feature.simple.SimpleFeature;
import org.opengis.feature.simple.SimpleFeatureType;
import org.opengis.feature.type.AttributeDescriptor;
import org.opengis.feature.type.AttributeType;
import org.opengis.feature.type.GeometryDescriptor;
import org.opengis.feature.type.GeometryType;

import java.io.IOException;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.sql.*;
import java.util.*;

/**
 * @author: linser
 * @Desc: 数据源 后面加Model是为了防止命名冲突
 * @create: 2024-01-28 20:22
 **/
public class MysqlDataStoreModel extends BaseDataStoreModel {


    public MysqlDataStoreModel() {
        super();
    }
    public MysqlDataStoreModel(DbInfo dbInfo) {
        super(dbInfo);
    }
    public MysqlDataStoreModel(DbInfo dbInfo, Map<String, Object> localConnectionDataMap) {
        super(dbInfo,localConnectionDataMap);
    }

    @Override
    public SimpleFeatureCollection getFeatureCollection(String tablename) throws IOException {
        FeatureSource<SimpleFeatureType, SimpleFeature> featureSource = this.dataStore.getFeatureSource(tablename);
        SimpleFeatureCollection features = (SimpleFeatureCollection) featureSource.getFeatures();
        // 定义 源 的属性和几何信息
        SimpleFeatureType orignFeatureType = featureSource.getSchema();
        //featureSource.
        // 定义要创建的要素类型（schema）
        SimpleFeatureTypeBuilder typeBuilder = new SimpleFeatureTypeBuilder();
        typeBuilder.setDefaultGeometry(orignFeatureType.getGeometryDescriptor().getLocalName());
        typeBuilder.setNamespaceURI(orignFeatureType.getName().getNamespaceURI());
        typeBuilder.setName(orignFeatureType.getName());
        typeBuilder.setAbstract(orignFeatureType.isAbstract());
        typeBuilder.setDescription(orignFeatureType.getDescription());

        // 添加原始特征类型的部分属性
        orignFeatureType.getAttributeDescriptors().forEach(attribute -> {
            // 判断是否应该添加该属性
            if(attribute instanceof GeometryDescriptorImpl){
                // 获取原始的空间字段描述
                GeometryDescriptor geometryDescriptor = (GeometryDescriptor) attribute;
                // 获取原始属性的几何类型
                AttributeType originalAttributeType = geometryDescriptor.getType();
                Class<?> orignGeometryBinding = originalAttributeType.getBinding();
                Class<?> targetGeometryBinding = orignGeometryBinding;
                if(Geometry.class.isAssignableFrom(orignGeometryBinding)){
                    if (orignGeometryBinding.equals(Geometry.class)) {
                        SimpleFeature feature = DataUtilities.first(features);
                        if(feature != null){
                            // 获取空间字段的属性名称，通常可能是 "geom", "location", "shape" 等
                            String geometryAttributeName = feature.getType().getGeometryDescriptor().getName().getLocalPart();
                            // 从特征中获取空间字段的值
                            Object geometryObject = feature.getAttribute(geometryAttributeName);
                            // 确认这是一个 Geometry 对象
                            if (geometryObject instanceof Geometry) {
                                // 获取具体的 Geometry 类型
                                targetGeometryBinding = geometryObject.getClass();
                            }
                        }
                    }
                }
                GeometryType newAttributeType = new GeometryTypeImpl(originalAttributeType.getName(),
                        targetGeometryBinding,
                        orignFeatureType.getCoordinateReferenceSystem(),
                        originalAttributeType.isIdentified(),
                        originalAttributeType.isAbstract(),
                        originalAttributeType.getRestrictions(),
                        originalAttributeType.getSuper(),
                        originalAttributeType.getDescription());
                GeometryDescriptor newGeometryDescriptor = new GeometryDescriptorImpl(
                        newAttributeType,
                        attribute.getName(),
                        attribute.getMinOccurs(),
                        attribute.getMaxOccurs(),
                        attribute.isNillable(),
                        attribute.getDefaultValue()
                );
                typeBuilder.add(newGeometryDescriptor);
            }else{
                typeBuilder.add(attribute);
            }
        });
        // 设置为新的 CoordinateReferenceSystem
        typeBuilder.setCRS(orignFeatureType.getCoordinateReferenceSystem());
        // 创建要素类型
        SimpleFeatureType targetFeatureType = typeBuilder.buildFeatureType();

        ListFeatureCollection listFeatureCollection = new ListFeatureCollection(targetFeatureType);
        try (SimpleFeatureIterator iterator = features.features()) {
            while (iterator.hasNext()) {
                SimpleFeature feature = iterator.next();
                Geometry geometry = (Geometry) feature.getDefaultGeometry();
                SimpleFeatureBuilder featureBuilder = new SimpleFeatureBuilder(targetFeatureType);
                Collection<Property> properties = feature.getProperties();
                Iterator<Property> propertyIterator = properties.iterator();
                while (propertyIterator.hasNext()) {
                    Property property = propertyIterator.next();
                    if(property.getValue() instanceof Geometry){
                        String currentVersion = this.getVersion();
                        //mysql读取是按照[纬度-经度]读取的，低版本的读取出来的一般是[经度-纬度]
                        if(!currentVersion.startsWith("8.")){
                            Geometry targetGeometry = TransformUtil.transFormGeom(geometry, CoordinateType.LatLon);
                            featureBuilder.set(property.getName(),targetGeometry);
                        }else{
                            featureBuilder.set(property.getName(),geometry);
                        }
                    }else {
                        featureBuilder.set(property.getName(),property.getValue());
                    }
                }
                listFeatureCollection.add(featureBuilder.buildFeature(feature.getID()));
            }
        }
        return listFeatureCollection;
    }

//    @Override
//    public List<DataTableModel> getDbTableLst() {
//        if (this.dbTableLst == null) {
//            synchronized(this) {
//                if (this.dbTableLst == null) {
//                    this.dbTableLst = new ArrayList();
//                    try {
//                        DataStore dataStore = this.getDataStore();
//                        if (dataStore != null) {
//                            String currentVersion = this.getVersion();
//                            String[] tableNames = dataStore.getTypeNames();
//                            //mysql8版本的比较特使需要过滤掉系统表
//                            if(currentVersion.startsWith("8.")){
//                                JDBCDataStore store = (JDBCDataStore)dataStore;
//                                Connection interconnection = store.getDataSource().getConnection();
//                                // 获取数据库元数据
//                                DatabaseMetaData metaData = interconnection.getMetaData();
//                                // 获取表信息的结果集
//                                ResultSet resultSet = metaData.getTables(this.getDbInfo().getDatabase(), null, null, new String[]{"TABLE"});
//                                // 遍历结果集，获取表名
//                                while (resultSet.next()) {
//                                    String tableName = resultSet.getString("TABLE_NAME");
//                                    DataTableModel dataTable = new DataTableModel(this);
//                                    dataTable.setTableName(tableName);
//                                    this.dbTableLst.add(dataTable);
//                                    //tableNames.add(tableName);
//                                }
//                            }else {
//
//                                if (tableNames != null) {
//                                    for(int i = 0; i < tableNames.length; ++i) {
//                                        String tableName = tableNames[i];
//                                        DataTableModel dataTable = new DataTableModel(this);
//                                        // 获取表的特征源
//                                        FeatureSource<SimpleFeatureType, SimpleFeature> featureSource = dataStore.getFeatureSource(new NameImpl(tableName));
//                                        // 判断是否为空间表
//                                        if (featureSource != null && featureSource.getSchema().getGeometryDescriptor() != null) {
//                                            dataTable.setSpatial(true);
//                                        }
//                                        dataTable.setTableName(tableName);
//                                        this.dbTableLst.add(dataTable);
//                                    }
//                                }
//                            }
//
//                        }
//                    }catch (SQLException | IOException e) {
//                        throw new RuntimeException(e);
//                    }
//                }
//            }
//        }
//
//        return this.dbTableLst;
//    }
}
